#ifndef GE_MESHINSTANCE
#define GE_MESHINSTANCE

#include "GE_Base.h"
namespace Syp
{
///A MeshInstance represents an instance of a mesh. Each Mesh can have multiple MeshInstances but not vice versa. MeshInstances increase efficiency by only loading resources once. A MeshInstance can point to a Mesh, Texture, Shader and Material. 
///
///A few key concepts should be understood about the default materials/textures. 
///1) A Mesh will recommend a default material.
///2) A Material will recommend a default Texture.
///3) These recommendations can be changed by the user. But the change should occur after the recommender has been used.
///For example if you want to use a different material, use the required mesh first. Then call useMaterial(yourchoice) to override the default material. Should you call useMesh again, the mesh's default material will be used. The reason for defaults is to reduce the workload of programmers and simplify code by reducing number of lines of code required to draw a mesh onscreen.
struct SYPAPI MeshInstance : public Node
{
	static MeshInstance* createMeshInstance();
	static void destroyMeshInstance(MeshInstance* mi);
	friend class Renderer;	
	bool visible;
	///The mesh it should use for drawing itself. 
	virtual void useMesh(BaseMesh* m);
	///Sets mesh to 0, this means that the instance will not be drawn. The MeshInstance is also removed from the SceneManager. 
	virtual void clearMesh();
	///The Material the instance should use to light itself. If not set, it will default to the Material provided by the mesh this MeshInstance is using. MeshInstance::useMaterial(Material* m) is more efficient than it's string counterpart whereas the String version is more convenient and safe. Should there be a need to individualise each MeshInstance's material, the user should make a new material make modifications to it and use the modified material. 
	void useMaterial(Material* m);
	void useMaterial(const String& filename);
	///Clears the material currently being used. The MeshInstance is also removed from the SceneManager because a material is required for rendering. 
	void clearMaterial();
	///Returns a pointer to the current Material. Modification to this material will affect the Material of all MeshInstances using this Material.Should there be a need to individualise each MeshInstance's material, the user should make a new material make modifications to it and use the modified material.
	Material* getMaterial();

	///Clears all resources being used by the MeshInstance. Mesh,texture and material are all released.
	virtual void clearAll();
	///Returns a pointer to the Mesh the instance is using.
	inline BaseMesh* getMesh()
	{
		return mesh;
	};
	
	///Toggles animation
	bool animate;
	///Animation playback rate, default is 1.0f
	float speed;
	///RenderMode for it to be rendered in Perspective/Ortho
	RenderMode mode;
	//An array of Renderable iterators representing this MeshInstance in the SceneManager. NOT for USER.
	//  Vector(  setIterator ); Vector with pairs in it. 
	std::vector< std::set<Renderable>::iterator  > renderables;
	
	///Time of animation in seconds at which this instance is playing at.
	float AnimTime;
	///Incase multiple renderables exist and call upon this MI to render another part of a mesh, the mesh will know not to increase it's AnimTime again in the same frame.
	double lastTransformedOn;	

	
private:
	MeshInstance();
	virtual ~MeshInstance();	
	///Texture ID of the texture used by the mesh.
	//TextureObj* textureID;
	///Pointer to the mesh 
	BaseMesh* mesh;
	///Pointer to the Material being used.
	Material* material;
	

};
}

#endif

